/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NewClientTablePanel.java
 *
 * Created on 20-nov-2009, 17:54:56
 */

package com.runwalk.video.gui.panels;

import java.awt.Component;
import java.beans.Beans;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ComboBoxEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.GroupLayout;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;

import org.jdesktop.beansbinding.AbstractBindingListener;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.beansbinding.Binding;
import org.jdesktop.beansbinding.BindingGroup;
import org.jdesktop.beansbinding.Bindings;
import org.jdesktop.beansbinding.ELProperty;
import org.jdesktop.beansbinding.Validator;
import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy;
import org.jdesktop.beansbinding.Binding.SyncFailure;
import org.jdesktop.el.impl.util.ReflectionUtil;
import org.jdesktop.swingbinding.JComboBoxBinding;
import org.jdesktop.swingbinding.SwingBindings;

import ca.odell.glazedlists.gui.TableFormat;

import com.runwalk.video.entities.City;
import com.runwalk.video.entities.Client;

/**
 *
 * @author Administrator
 */
public class NewClientTablePanel extends AbstractTablePanel<Client> {

	public static void main(String[] args) {
		new NewClientTablePanel();
	}

	private JButton addClientButton = new JButton();
	private JButton removeClientButton = new JButton();
	private JTextField searchField = new JTextField();
	private JLabel jLabel1 = new JLabel();

	private JButton removeAnalysisButton = new JButton();
	private JButton addAnalysisButton = new JButton();

	/** Creates new form NewClientTablePanel */
	public NewClientTablePanel() {
		super(null);
		//        super(RunwalkVideoApp.getApplication().getClientTableModel());
		initComponents();
		JFrame frame = new JFrame();
		frame.add(this);
		frame.pack();
		frame.setVisible(true);
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
	private void initComponents() {//GEN-BEGIN:initComponents
		bindingGroup = new BindingGroup();
		entityManager = Beans.isDesignTime() ? null : Persistence.createEntityManagerFactory("runwalk-video").createEntityManager();
		
		clientQuery = entityManager.createNamedQuery("findAllClients"); // NOI18N
		clientQuery.setHint("eclipselink.left-join-fetch", "c.unobservableAnalyses.recording");
		clientQuery.setHint("eclipselink.left-join-fetch", "c.city");
		
//		clientQuery = Beans.isDesignTime() ? null  : entityManager.createQuery("Select DISTINCT c from Client c LEFT JOIN FETCH c.analyses");
		clientList = Beans.isDesignTime() ? Collections.emptyList() : clientQuery.getResultList();
		mainPanel = new JPanel();
		cityQuery = Beans.isDesignTime() ? null : entityManager.createNamedQuery("findAllCities");
		cityList = Beans.isDesignTime() ? Collections.emptyList() : cityQuery.getResultList();
		genderRadioButtonGroup = new ButtonGroup();
		detailTabbedPane = new JTabbedPane();
		analysisInfoPanel = new JPanel();
		analysisTableScrollPane = new JScrollPane();
		analysisTable = new JTable();
		clientInfoPanel = new JPanel();
		nameLabel = new JLabel();
		firstnameField = new JTextField();
		nameField = new JTextField();
		organisationLabel = new JLabel();
		organisationField = new JTextField();
		addressField = new JTextField();
		addressLabel = new JLabel();
		taxLabel = new JLabel();
		taxField = new JTextField();
		emailLabel = new JLabel();
		emailField = new JTextField();
		zipcodeLabel = new JLabel();
		zipcodeField = new JComboBox();
		locationLabel = new JLabel();
		locationField = new JComboBox();
		phoneLabel = new JLabel();
		phoneField = new JTextField();
		firstnameLabel = new JLabel();
		maleRadioButton = new JRadioButton();
		femaleRadioButton = new JRadioButton();
		birthdateLabel = new JLabel();
		birthdateField = new JFormattedTextField();
		genderLabel = new JLabel();
		jPanel1 = new JPanel();
		clientTableScrollPane = new JScrollPane();
		clientTable = getTable();
		clientTablePanel = new JPanel();
		final JTextArea comments = new JTextArea();
		JScrollPane commentsScrollPane = new JScrollPane();

/*		EventList<Client> glazedClients = GlazedLists.threadSafeList(GlazedLists.eventList(clientList));
        ObservableElementList.Connector<Client> idolConnector = GlazedLists.beanConnector(Client.class);
        EventList<Client> observedClients = new ObservableElementList<Client>(glazedClients, idolConnector);
		SortedList<Client> sortedClients = SortedList.create(observedClients);
        EventSelectionModel<Client> clientSelectionModel = new EventSelectionModel(sortedClients);
        clientSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        final EventList<Client> selectedClients = clientSelectionModel.getSelected();
        
		CollectionList<Client, Analysis> analyses = new CollectionList(selectedClients, new CollectionList.Model<Client, Analysis>() {

			@Override
			public List<Analysis> getChildren(Client parent) {
				return parent.getAnalyses();
			}
        	
		});
        

        SortedList<Analysis> sortedAnalyses = new SortedList<Analysis>(analyses);
        
        // build a JTable
        clientTable = new JTable(new EventTableModel<Client>(sortedClients, new ClientTablePanel.ClientTableFormat()));
        TableComparatorChooser.install(clientTable, sortedClients, TableComparatorChooser.MULTIPLE_COLUMN_MOUSE);
        clientTable.setSelectionModel(clientSelectionModel);
        clientTable.setColumnSelectionAllowed(false);
        analysisTable = new JTable(new EventTableModel<Analysis>(sortedAnalyses, new AnalysisTableFormat()));
        TableComparatorChooser.install(analysisTable, sortedAnalyses, TableComparatorChooser.MULTIPLE_COLUMN_MOUSE);
        EventSelectionModel<Analysis> analysisSelectionModel = new EventSelectionModel(sortedAnalyses);
        analysisSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        analysisTable.setSelectionModel(analysisSelectionModel);*/
        
		mainPanel.setName("mainPanel"); // NOI18N

		GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
		mainPanel.setLayout(mainPanelLayout);
		mainPanelLayout.setHorizontalGroup(
				mainPanelLayout.createParallelGroup(Alignment.LEADING)
				.addGap(0, 100, Short.MAX_VALUE)
		);
		mainPanelLayout.setVerticalGroup(
				mainPanelLayout.createParallelGroup(Alignment.LEADING)
				.addGap(0, 100, Short.MAX_VALUE)
		);

		detailTabbedPane.setName("detailTabbedPane"); // NOI18N

		analysisInfoPanel.setName("analysisInfoPanel"); // NOI18N

		analysisTableScrollPane.setName("analysisTableScrollPane"); // NOI18N

//		analysisTable.setColumnSelectionAllowed(true);

		analysisTable.setName("analysisTable"); // NOI18N

        ELProperty<Object, Object> tableRowSelectedProperty = ELProperty.create("${selectedElement != null}");
		/*ELProperty eLProperty = ELProperty.create("${selectedElement.analyses}");
		JTableBinding jTableBinding = SwingBindings.createJTableBinding(UpdateStrategy.READ_WRITE, clientTable, eLProperty, analysisTable);
		ColumnBinding columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${timeStamp}"));
		columnBinding.setColumnName("Time Stamp");
		columnBinding.setColumnClass(String.class);
		columnBinding.setEditable(false);
		columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${article}"));
		columnBinding.setColumnName("Article");

		Query query = entityManager.createQuery("select OBJECT(ar) from Articles ar"); // NOI18N
		ObservableList<Articles> articleList = ObservableCollections.observableList(query.getResultList());

		JComboBox shoes = new JComboBox();
		shoes.setFont(AppSettings.MAIN_FONT);
		JComboBoxBinding<Articles, List<Articles>, JComboBox> cb = SwingBindings.createJComboBoxBinding(AutoBinding.UpdateStrategy.READ, articleList, shoes);
		cb.bind();

		columnBinding.setEditor(new DefaultCellEditor(shoes));
		columnBinding.setColumnClass(Articles.class);
		columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${recording.keyframeCount}"));
		columnBinding.setColumnName("Recording.keyframe Count");
		columnBinding.setColumnClass(Integer.class);
		columnBinding.setEditable(false);
		columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${recording.duration}"));
		columnBinding.setColumnName("Recording.duration");
		columnBinding.setConverter(new Converter<Long, String>() {

			@Override
			public String convertForward(Long arg0) {
				return arg0 == null ? "<geen>" : AppUtil.formatDate(new Date(arg0), AppUtil.DURATION_FORMATTER);
			}

			@Override
			public Long convertReverse(String arg0) {
				return null;
			}

		});
		columnBinding.setColumnClass(Long.class);
		columnBinding.setEditable(false);
		columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${recording}"));
		columnBinding.setColumnName("Recording.recorded");
		columnBinding.setRenderer(new CustomJTableRenderer(getTable().getDefaultRenderer(JButton.class)));
		analysisTable.addMouseListener(new JTableButtonMouseListener());
		columnBinding.setEditable(false);
		columnBinding.setConverter(new Converter<Recording, JButton>() {

			@Override
			public JButton convertForward(final Recording recording) {
				final JButton button = new JButton("open");
				button.setEnabled(recording != null);
				button.setFont(AppSettings.MAIN_FONT);
				button.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent e) {
						if (button.isEnabled()) {
							RunwalkVideoApp.getApplication().getMediaControls().playFile(recording);
						}
					}
				});
				return button;
			}

			@Override
			public Recording convertReverse(JButton button) {
				return null;
			}

		});
		jTableBinding.setSourceNullValue(Collections.emptyList());
		jTableBinding.setSourceUnreadableValue(Collections.emptyList());
		bindingGroup.addBinding(jTableBinding);
		jTableBinding.bind();*/
		analysisTableScrollPane.setViewportView(analysisTable);
		ResourceBundle bundle = ResourceBundle.getBundle("com/runwalk/video/gui/resources/AbstractTableModel");
		analysisTable.getColumnModel().getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		analysisTable.getColumnModel().getColumn(0).setHeaderValue(bundle.getString("analysisTableModel.columnModel.col1")); // NOI18N
		analysisTable.getColumnModel().getColumn(1).setHeaderValue(bundle.getString("analysisTableModel.columnModel.col2")); // NOI18N
		analysisTable.getColumnModel().getColumn(2).setHeaderValue(bundle.getString("analysisTableModel.columnModel.col3")); // NOI18N
		analysisTable.getColumnModel().getColumn(3).setHeaderValue(bundle.getString("analysisTableModel.columnModel.col4")); // NOI18N
//		analysisTable.getColumnModel().getColumn(4).setHeaderValue(bundle.getString("analysisTableModel.columnModel.col5")); // NOI18N

		commentsScrollPane.setName("commentsScrollPane"); // NOI18N

		comments.setColumns(20);
		comments.setRows(5);
		comments.setName("comments"); // NOI18N
		
		Binding binding;
/*		Binding binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, analysisTable, ELProperty.create("${selectedElement.comments}"), comments, BeanProperty.create("text"));
		bindingGroup.addBinding(binding);

		binding = Bindings.createAutoBinding(UpdateStrategy.READ, analysisTable, tableRowSelectedProperty, comments, BeanProperty.create("enabled"));
        binding.setSourceNullValue(false);
        binding.setSourceUnreadableValue(false);
        bindingGroup.addBinding(binding);*/

		commentsScrollPane.setViewportView(comments);

        removeAnalysisButton.setText("Verwijder analyse");
        removeAnalysisButton.setName("removeAnalysisButton"); // NOI18N

        addAnalysisButton.setText("Voeg analyse toe");
        addAnalysisButton.setName("addAnalysisButton");
       /* addAnalysisButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (!selectedClients.isEmpty()) {
					Client selectedClient = selectedClients.get(0);
					Analysis analysis = new Analysis(selectedClient);
					selectedClient.addAnalysis(analysis);
				}
			}
        	
        });*/
        // NOI18N

        GroupLayout analysisInfoPanelLayout = new GroupLayout(analysisInfoPanel);
        analysisInfoPanel.setLayout(analysisInfoPanelLayout);
        analysisInfoPanelLayout.setHorizontalGroup(
            analysisInfoPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, analysisInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(analysisInfoPanelLayout.createParallelGroup(Alignment.TRAILING)
                    .addComponent(commentsScrollPane, GroupLayout.DEFAULT_SIZE, 512, Short.MAX_VALUE)
                    .addComponent(analysisTableScrollPane, GroupLayout.DEFAULT_SIZE, 512, Short.MAX_VALUE)
                    .addGroup(Alignment.LEADING, analysisInfoPanelLayout.createSequentialGroup()
                        .addComponent(addAnalysisButton)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(removeAnalysisButton)))
                .addContainerGap())
        );
        analysisInfoPanelLayout.setVerticalGroup(
            analysisInfoPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, analysisInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(analysisTableScrollPane, GroupLayout.DEFAULT_SIZE, 98, Short.MAX_VALUE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(analysisInfoPanelLayout.createParallelGroup(Alignment.BASELINE)
                    .addComponent(addAnalysisButton)
                    .addComponent(removeAnalysisButton))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(commentsScrollPane, GroupLayout.PREFERRED_SIZE, 49, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );


		ResourceBundle bundle1 = ResourceBundle.getBundle("com/runwalk/video/resources/RunwalkVideoApp"); // NOI18N
		detailTabbedPane.addTab(bundle1.getString("analysisInfoPanel.title"), analysisInfoPanel); // NOI18N

		clientInfoPanel.setName("clientInfoPanel"); // NOI18N

		ResourceBundle bundle2 = ResourceBundle.getBundle("com/runwalk/video/gui/resources/ClientInfoPanel"); // NOI18N
		nameLabel.setText(bundle2.getString("nameLabel.text")); // NOI18N
		nameLabel.setName("nameLabel"); // NOI18N

		firstnameField.setName("firstnameField"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.name}"), firstnameField, BeanProperty.create("text"));
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, firstnameField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		nameField.setName("nameField"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.firstname}"), nameField, BeanProperty.create("text"));
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, nameField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		organisationLabel.setText(bundle2.getString("organisationLabel.text")); // NOI18N
		organisationLabel.setName("organisationLabel"); // NOI18N

		organisationField.setName("organisationField"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.organization}"), organisationField, BeanProperty.create("text"));
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, organisationField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		addressField.setName("addressField"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.address}"), addressField, BeanProperty.create("text"));
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, addressField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		addressLabel.setText(bundle2.getString("addressLabel.text")); // NOI18N
		addressLabel.setName("adressLabel"); // NOI18N

		taxLabel.setText(bundle2.getString("taxNoLabel.text")); // NOI18N
		taxLabel.setName("btwLabel"); // NOI18N

		taxField.setName("taxField"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.btwnr}"), taxField, BeanProperty.create("text"), "emailBinding");
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, taxField, BeanProperty.create("enabled"));
		binding.setValidator(new Validator () {

			public Validator.Result validate(Object arg) {
				String regexPattern = "[0-9]{9}";
				Pattern pattern = Pattern.compile(regexPattern);
				Matcher matcher = pattern.matcher(arg.toString());
				if(!matcher.matches()){
					return new Result(null, "Btwnr. moet 9 cijfers bevatten");
				}
				return null;    
			}
		});
		bindingGroup.addBinding(binding);

		emailLabel.setText(bundle2.getString("emailLabel.text")); // NOI18N
		emailLabel.setName("emailLabel"); // NOI18N

		emailField.setName("emailField"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.emailAddress}"), emailField, BeanProperty.create("text_ON_FOCUS_LOST"));
		binding.setValidator(new Validator() {
					
					public Validator.Result validate(Object arg) {        
						String expression = "^[\\w\\.-]+@([\\w\\-]+\\.)+[A-Z]{2,4}$";
						Pattern pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE);
						Matcher matcher = pattern.matcher(arg.toString());
						if(!matcher.matches()){
							return new Result(null, "Email adres is niet correct geformatteerd");
						}
						return null;
					}
				}
		);
		binding.addBindingListener(new AbstractBindingListener() {
			
			@Override
			public void syncFailed(Binding binding1, SyncFailure syncfailure) {
				System.out.println(syncfailure.toString());
			}
			
		});
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, emailField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);  

		zipcodeLabel.setText(bundle2.getString("zipcodeLabel.text")); // NOI18N
		zipcodeLabel.setName("zipcodeLabel"); // NOI18N
		zipcodeField.setName("zipcodeField"); // NOI18N

		JComboBoxBinding jComboBoxBinding = SwingBindings.createJComboBoxBinding(UpdateStrategy.READ_WRITE, cityList, zipcodeField);
		bindingGroup.addBinding(jComboBoxBinding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.city}"), zipcodeField, BeanProperty.create("selectedItem"), "zipcodeBinding");
		binding.setSourceNullValue(null);
		binding.setSourceUnreadableValue(null);
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, zipcodeField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		locationLabel.setText(bundle2.getString("locationLabel.text")); // NOI18N
		locationLabel.setName("locationLabel"); // NOI18N
		locationField.setName("locationField"); // NOI18N

		jComboBoxBinding = SwingBindings.createJComboBoxBinding(UpdateStrategy.READ_WRITE, cityList, locationField);
		bindingGroup.addBinding(jComboBoxBinding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.city}"), locationField, BeanProperty.create("selectedItem"));
		binding.setSourceNullValue(null);
		binding.setSourceUnreadableValue(null);
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, locationField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		class CityInfoRenderer extends DefaultListCellRenderer {

			@Override
			public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
				JLabel result = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
				City city = (City) value;
				result.setText(city.getCode() + " " + city.getName());
				return result;
			}
		}

		class CityInfoEditor extends BasicComboBoxEditor {

			private String methodName;
			private Class<?> methodClass;

			public CityInfoEditor(ComboBoxEditor origEditor, Class<?> methodClass, String methodName) {
				super();
				this.methodName = methodName;
				this.methodClass = methodClass;
				editor.setBorder(((JComponent) origEditor.getEditorComponent()).getBorder());
			}

			@Override
			public void setItem(Object anObject) {
				if (anObject != null && methodClass.isAssignableFrom(anObject.getClass())) {
					Method method = ReflectionUtil.getMethod(anObject, methodName, new Class<?>[] {});
					try {
						super.setItem(method.invoke(anObject, new Object[] {}));
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					}
				} else {
					super.setItem(anObject);
				}
			}

			@Override
			public Object getItem() {
				Object value = super.getItem();
				City selectedCity = null;
				List<?> resultList = null;
				if (value instanceof String) {
					selectedCity = (City) locationField.getSelectedItem();
					Query query = entityManager.createNamedQuery("findByName");
					query.setParameter("name", value);
					resultList = query.getResultList();
				} else if (int.class.isAssignableFrom(value.getClass()) || value instanceof Integer) {
					selectedCity = (City) zipcodeField.getSelectedItem();
					if (!value.equals(selectedCity.getCode())) {
						Query query = entityManager.createNamedQuery("findByZipCode");
						query.setParameter("zipCode", value);
						resultList = query.getResultList();
					}
				}
				return resultList != null && resultList.size() > 0 ? resultList.get(0) : selectedCity;
			}
		}

		locationField.setEditor(new CityInfoEditor(locationField.getEditor(), City.class, "getName"));
		locationField.setRenderer(new CityInfoRenderer());
		locationField.setEditable(true);

/*		AutoCompletion ac = new AutoCompletion(this.locationField, new ComboBoxSearchable(locationField) {
			@Override
			protected String convertElementToString(Object object) {
				return ((City) object).getName();
			}
		});*/

		zipcodeField.setEditor(new CityInfoEditor(zipcodeField.getEditor(), City.class, "getCode"));
		zipcodeField.setRenderer(new CityInfoRenderer());
		zipcodeField.setEditable(true);

/*		AutoCompletion ac2 = new AutoCompletion(this.zipcodeField, new ComboBoxSearchable(zipcodeField) {
			@Override
			protected String convertElementToString(Object object) {
				return Integer.toString(((City) object).getCode());
			}
		});*/

		phoneLabel.setText(bundle2.getString("telephoneLabel.text")); // NOI18N
		phoneLabel.setName("phoneLabel"); // NOI18N

		phoneField.setName("phoneField"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.phone}"), phoneField, BeanProperty.create("text"));
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, phoneField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		firstnameLabel.setText(bundle2.getString("firstnameLabel.text")); // NOI18N
		firstnameLabel.setName("firstnameLabel"); // NOI18N

		JRadioButton maleRadioButton  = new JRadioButton();
		maleRadioButton.setText(bundle2.getString("maleRadioButton.text")); // NOI18N
		maleRadioButton.setName("maleRadioButton"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.male}"), maleRadioButton, BeanProperty.create("selected"));
		//bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${!selectedElement.male}"), femaleRadioButton, BeanProperty.create("selected"));
	//	bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, maleRadioButton, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, femaleRadioButton, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		femaleRadioButton.setText(bundle2.getString("femaleRadioButton.text")); // NOI18N
		femaleRadioButton.setName("femaleRadioButton"); // NOI18N

		birthdateLabel.setText(bundle2.getString("birthdateLabel.text")); // NOI18N
		birthdateLabel.setName("birthdateLabel"); // NOI18N

		birthdateField.setFormatterFactory(new DefaultFormatterFactory(new DateFormatter(new SimpleDateFormat("dd/MM/yyyy"))));
		birthdateField.setInputVerifier(new InputVerifier() {
			@Override
			public boolean shouldYieldFocus(JComponent input) {
				boolean inputOK = verify(input);
				if (inputOK) {
					return true;
				}
				String failedVerificationMessage = "Date must be in the dd/MM/yyyy format. For example: Apr 17, 2008";
				JOptionPane.showMessageDialog(null, failedVerificationMessage, "Invalid Date Format", JOptionPane.WARNING_MESSAGE);
				//Reinstall the input verifier.
				input.setInputVerifier(this);
				return false;
			}
			public boolean verify(JComponent input) {
				boolean result = ((JFormattedTextField) input).isEditValid();
				if (!(input instanceof JFormattedTextField)) {
					result = true; 
				}
				return result;
			}

		});
		birthdateField.setName("birthdateField"); // NOI18N

		binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, this, ELProperty.create("${selectedElement.birthdate}"), birthdateField, BeanProperty.create("value"));
		bindingGroup.addBinding(binding);
		binding = Bindings.createAutoBinding(UpdateStrategy.READ, this, tableRowSelectedProperty, birthdateField, BeanProperty.create("enabled"));
		bindingGroup.addBinding(binding);

		genderLabel.setText(bundle2.getString("genderLabel.text")); // NOI18N
		genderLabel.setName("genderLabel"); // NOI18N

        GroupLayout clientInfoPanelLayout = new GroupLayout(clientInfoPanel);
        clientInfoPanel.setLayout(clientInfoPanelLayout);
        clientInfoPanelLayout.setHorizontalGroup(
            clientInfoPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(clientInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.LEADING, false)
                    .addComponent(genderLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(nameLabel, GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE)
                    .addComponent(addressLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(organisationLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(zipcodeLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(34, 34, 34)
                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.LEADING)
                    .addComponent(addressField, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE)
                    .addGroup(clientInfoPanelLayout.createSequentialGroup()
                        .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.LEADING)
                            .addGroup(clientInfoPanelLayout.createSequentialGroup()
                                .addComponent(maleRadioButton)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(femaleRadioButton))
                            .addComponent(organisationField, GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                            .addComponent(firstnameField, GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                            .addComponent(emailField, GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE))
                        .addGap(16, 16, 16)
                        .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.LEADING)
                            .addGroup(clientInfoPanelLayout.createSequentialGroup()
                                .addComponent(firstnameLabel)
                                .addGap(37, 37, 37))
                            .addGroup(clientInfoPanelLayout.createSequentialGroup()
                                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.LEADING)
                                    .addComponent(taxLabel)
                                    .addComponent(phoneLabel, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)
                                    .addComponent(birthdateLabel))
                                .addGap(21, 21, 21)
                                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.LEADING)
                                    .addComponent(nameField, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                                    .addComponent(birthdateField, GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                                    .addComponent(taxField, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
                                    .addComponent(phoneField, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)))))
                    .addGroup(Alignment.TRAILING, clientInfoPanelLayout.createSequentialGroup()
                        .addComponent(zipcodeField, 0, 140, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addComponent(locationLabel, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)
                        .addGap(23, 23, 23)
                        .addComponent(locationField, 0, 130, Short.MAX_VALUE)))
                .addContainerGap())
        );
        clientInfoPanelLayout.setVerticalGroup(
            clientInfoPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(clientInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.BASELINE)
                    .addComponent(firstnameField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(nameField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(nameLabel)
                    .addComponent(firstnameLabel))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.BASELINE)
                    .addComponent(maleRadioButton)
                    .addComponent(femaleRadioButton)
                    .addComponent(birthdateField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(genderLabel)
                    .addComponent(birthdateLabel))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.BASELINE)
                    .addComponent(organisationField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(taxField, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
                    .addComponent(organisationLabel)
                    .addComponent(taxLabel))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.BASELINE)
                    .addComponent(emailField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(phoneField, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
                    .addComponent(emailLabel)
                    .addComponent(phoneLabel))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.BASELINE)
                    .addComponent(addressField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(addressLabel))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(clientInfoPanelLayout.createParallelGroup(Alignment.BASELINE)
                    .addComponent(zipcodeField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(zipcodeLabel)
                    .addComponent(locationField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(locationLabel))
                .addContainerGap(32, Short.MAX_VALUE))
        );
        
		genderRadioButtonGroup.add(maleRadioButton);
		genderRadioButtonGroup.add(femaleRadioButton);

		detailTabbedPane.addTab(bundle1.getString("clientInfoPanel.title"), clientInfoPanel); // NOI18N

		ResourceBundle bundle3 = ResourceBundle.getBundle("com/runwalk/video/gui/resources/ClientTablePanel");
		jPanel1.setBorder(BorderFactory.createTitledBorder(bundle3.getString("borderPanel.border.title"))); // NOI18N
		jPanel1.setName("jPanel1"); // NOI18N

		clientTableScrollPane.setName("clientTableScrollPane"); // NOI18N

		clientTable.setName("clientTable"); // NOI18N
/*
		jTableBinding = SwingBindings.createJTableBinding(UpdateStrategy.READ_WRITE, clientList, clientTable);
		columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${id}"));
		columnBinding.setColumnName("Id");
		columnBinding.setColumnClass(Long.class);
		columnBinding.setEditable(false);
		columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${firstname}"));
		columnBinding.setColumnName("Firstname");
		columnBinding.setColumnClass(String.class);
		columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${name}"));
		columnBinding.setColumnName("Name");
		columnBinding.setColumnClass(String.class);
		columnBinding = jTableBinding.addColumnBinding(ELProperty.create("${lastAnalysisDate}"));
		columnBinding.setConverter(new Converter<Date, String>() {

			@Override
			public String convertForward(Date arg0) {
				return arg0.toString();
			}

			@Override
			public Date convertReverse(String arg0) {
				try {
					return DateFormat.getInstance().parse(arg0);
				} catch (ParseException e) {
					return null;
				}
			}
		});
		columnBinding.setColumnName("Formatted Last Analysis Date");
		columnBinding.setColumnClass(String.class);
		columnBinding.setEditable(false);
		bindingGroup.addBinding(jTableBinding);
		jTableBinding.bind();*/
		clientTableScrollPane.setViewportView(clientTable);
		clientTable.getColumnModel().getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		clientTable.getColumnModel().getColumn(0).setMinWidth(20);
		clientTable.getColumnModel().getColumn(0).setPreferredWidth(30);
		clientTable.getColumnModel().getColumn(0).setMaxWidth(30);
		clientTable.getColumnModel().getColumn(0).setHeaderValue(bundle.getString("clientTableModel.columnModel.col1")); // NOI18N
		clientTable.getColumnModel().getColumn(1).setHeaderValue(bundle.getString("clientTableModel.columnModel.col2")); // NOI18N
		clientTable.getColumnModel().getColumn(2).setHeaderValue(bundle.getString("clientTableModel.columnModel.col3")); // NOI18N
		clientTable.getColumnModel().getColumn(3).setPreferredWidth(60);
		clientTable.getColumnModel().getColumn(3).setHeaderValue(bundle.getString("clientTableModel.columnModel.col4")); // NOI18N

		 addClientButton.setText("Voeg klant toe");
	        addClientButton.setName("addClientButton"); // NOI18N

	        removeClientButton.setText("Verwijder klant");
	        removeClientButton.setName("removeClientButton"); // NOI18N

	        searchField.setName("searchField"); // NOI18N

	        jLabel1.setText("test");
	        jLabel1.setName("jLabel1"); // NOI18N
		
	        GroupLayout clientTablePanelLayout = new GroupLayout(clientTablePanel);
	        clientTablePanel.setLayout(clientTablePanelLayout);
	        clientTablePanelLayout.setHorizontalGroup(
	            clientTablePanelLayout.createParallelGroup(Alignment.LEADING)
	            .addGroup(clientTablePanelLayout.createSequentialGroup()
	                .addComponent(addClientButton)
	                .addPreferredGap(ComponentPlacement.RELATED)
	                .addComponent(removeClientButton)
	                .addPreferredGap(ComponentPlacement.RELATED, 195, Short.MAX_VALUE)
	                .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, 19, GroupLayout.PREFERRED_SIZE)
	                .addPreferredGap(ComponentPlacement.UNRELATED)
	                .addComponent(searchField, GroupLayout.PREFERRED_SIZE, 106, GroupLayout.PREFERRED_SIZE))
	            .addComponent(clientTableScrollPane, GroupLayout.DEFAULT_SIZE, 540, Short.MAX_VALUE)
	        );
	        clientTablePanelLayout.setVerticalGroup(
	            clientTablePanelLayout.createParallelGroup(Alignment.LEADING)
	            .addGroup(Alignment.TRAILING, clientTablePanelLayout.createSequentialGroup()
	                .addComponent(clientTableScrollPane, GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)
	                .addPreferredGap(ComponentPlacement.RELATED)
	                .addGroup(clientTablePanelLayout.createParallelGroup(Alignment.BASELINE)
	                    .addComponent(addClientButton)
	                    .addComponent(removeClientButton)
	                    .addComponent(searchField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
	                    .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, 14, GroupLayout.PREFERRED_SIZE)))
	        );

        GroupLayout layout = new GroupLayout(this);
        setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(Alignment.TRAILING)
                    .addComponent(clientTablePanel, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(detailTabbedPane, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(clientTablePanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(detailTabbedPane, GroupLayout.PREFERRED_SIZE, 221, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

		detailTabbedPane.getAccessibleContext().setAccessibleName(bundle1.getString("clientTabbedPane.title")); // NOI18N

		bindingGroup.bind();
	}//GEN-END:initComponents

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private JTextField addressField;
	private JLabel addressLabel;
	private JPanel analysisInfoPanel;
	private JTable analysisTable;
	private JScrollPane analysisTableScrollPane;
	private JFormattedTextField birthdateField;
	private JLabel birthdateLabel;
	private List<City> cityList;
	private Query cityQuery;
	private JPanel clientInfoPanel;
	private List<Client> clientList;
	private Query clientQuery;
	private JTable clientTable;
	private JScrollPane clientTableScrollPane;
	private JTabbedPane detailTabbedPane;
	private JTextField emailField;
	private JLabel emailLabel;
	private EntityManager entityManager;
	private JRadioButton femaleRadioButton;
	private JTextField firstnameField;
	private JLabel firstnameLabel;
	private JLabel genderLabel;
	private ButtonGroup genderRadioButtonGroup;
	private JPanel jPanel1;
	private JComboBox locationField;
	private JLabel locationLabel;
	private JPanel mainPanel;
	private JRadioButton maleRadioButton;
	private JTextField nameField;
	private JLabel nameLabel;
	private JTextField organisationField;
	private JLabel organisationLabel;
	private JTextField phoneField;
	private JLabel phoneLabel;
	private JTextField taxField;
	private JLabel taxLabel;
	private JComboBox zipcodeField;
	private JLabel zipcodeLabel;
	private BindingGroup bindingGroup;
	
	private JPanel clientTablePanel;
	// End of variables declaration//GEN-END:variables
	
	
	@Override
	public TableFormat<Client> getTableFormat() {
		// TODO Auto-generated method stub
		return null;
	}

}
